﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.DirectoryServices;
using System.Net;
using System.Web.Services;
using shfa.snomtastic.data;
using shfa.snomtastic.data.business;
using shfa.snomtastic.data.security;
using System.Threading;

namespace shfa.snomtastic.root.services
{
    /// <summary>
    /// Summary description for UpdatePassword
    /// </summary>
    [WebService(Namespace = "http://shfa.nsw.gov.au/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class user : WebService
    {
        public user() { }

        #region Web Methods

        [WebMethod]
        public bool UpdatePassword(string userSID, string userPassword)
        {
            bool bUpdated = false;
            adSecurity ad = new adSecurity();
            DirectoryEntry de = ad.GetUserBySID(userSID);
            if (de != null)
            {
                string userPrincipalName = de.Properties["userPrincipalName"][0].ToString();
                if (userPrincipalName != string.Empty)
                {
                    UserController uc = new UserController();
                    List<UserInfo> uiList = uc.SelectUsers();

                    RijndaelEnhanced re = new RijndaelEnhanced();
                    string encPassword = re.Encrypt(userPassword);

                    foreach (UserInfo ui in uiList)
                    {
                        if (ui.UserName == userPrincipalName)
                        {
                            ui.Password = encPassword;
                            ui.PasswordUpdate = DateTime.UtcNow;


                            uc.UpdateUser(ui);

                            PhoneController pc = new PhoneController();
                            List<PhoneInfo> piList = pc.SelectPhonesByUser(ui.UserId);
                            foreach (PhoneInfo pi in piList)
                            {
                                pi.RegistrationFailed = false;
                                pc.UpdatePhone(pi);
                                ResetPhones(ui.UserId);
                            }


                            bUpdated = true;
                        }
                    }
                }
            }

            return bUpdated;
        }

        [WebMethod]
        public bool NeedPasswordUpdate(string userSid)
        {
            bool bNeedsUpdate = false;
            string userPrincipalName = "";
            DirectoryEntry de = GetUser(userSid);
            if (de != null)
            {
                userPrincipalName = de.Properties["userPrincipalName"][0].ToString();
                UserController uc = new UserController();
                List<UserInfo> uiList = uc.SelectUsers();
                foreach (UserInfo ui in uiList)
                {
                    if (ui.UserName == userPrincipalName)
                    {

                        ui.LastAccessDate = DateTime.UtcNow;
                        ui.PasswordUpdateAD = common.GetDateFromLargeInteger(de.Properties["pwdLastSet"][0]);
                        if (ui.Password == string.Empty)
                        {
                            bNeedsUpdate = true;
                            LogEvent(userPrincipalName, userSid, "Password Not Set", "Warning");
                        }
                        if (ui.PasswordUpdate == null)
                        {
                            bNeedsUpdate = true;
                            LogEvent(userPrincipalName, userSid, "New User", "Warning");
                        }
                        else
                        {
                            if (ui.PasswordUpdate < ui.PasswordUpdateAD)
                            {
                                bNeedsUpdate = true;
                                LogEvent(userPrincipalName, userSid, "Active Directory Updated", "Information");
                            }
                        }
                        if (!bNeedsUpdate)
                        {
                            PhoneController pc = new PhoneController();
                            List<PhoneInfo> pilist = pc.SelectPhonesByUser(ui.UserId);
                            foreach (PhoneInfo pi in pilist)
                            {
                                if (pi.RegistrationFailed)
                                {
                                    bNeedsUpdate = true;
                                    LogEvent(userPrincipalName, userSid, "Registration Failed", "Error");

                                }
                            }
                        }

                        uc.UpdateUser(ui);

                    }
                }
            }

            return bNeedsUpdate;


        }

        [WebMethod]
        public bool isValidCredentials(string userName, string passWord)
        {
            adSecurity ad = new adSecurity();
            return ad.isValidCredentials(userName, passWord);
        }

        [WebMethod]
        public UserPhoneInfo getUserPhoneInfo(string userSID)
        {
            string userPrincipalName = GetUserPrincipalName(userSID);
            if (userPrincipalName != null && userPrincipalName != string.Empty)
            {
                UserController uc = new UserController();
                List<UserInfo> uiList = uc.SelectUsers();
                foreach (UserInfo ui in uiList)
                {
                    if (ui.UserName == userPrincipalName)
                    {
                        DirectoryEntry de = GetUser(userSID);
                        PhoneController pc = new PhoneController();
                        List<PhoneInfo> piList = pc.SelectPhonesByUser(ui.UserId);

                        if (piList.Count == 1)
                        {
                            PhoneInfo pi = piList[0];
                            RijndaelEnhanced re = new RijndaelEnhanced();
                            AppConfig ac = new AppConfig();

                            UserPhoneInfo upi = new UserPhoneInfo();
                            upi.PhoneIp = pi.IpAddress;
                            upi.LoginName = ui.UserName;
                            upi.LoginPass = re.Decrypt(ui.Password);
                            upi.Domain = ac.Items["Domain"];
                            upi.OcsServer = ac.Items["OcsServer"];
                            upi.Transport = ac.Items["Transport"];
                            upi.Http_User = ac.Items["http_user"];
                            upi.Http_Pass = re.Decrypt(ac.Items["http_pass"]);

                            if (de != null)
                            {
                                upi.UriName = de.Properties["msRTCSIP-PrimaryUserAddress"].Value.ToString();
                            }
                            else
                            {
                                upi.UriName = "sip:" + ui.UserName;
                            }

                            return upi;

                        }
                    }
                }

            }

            return null;
        }

        [WebMethod]
        public void SendPhoneCommand(string phoneIp, PhoneCommand.CommandType cmd)
        {
            PhoneCommand pc = new PhoneCommand(phoneIp, cmd);
            pc.SendCommand();
        }


        #endregion

        #region Helper Methods

        private string GetUserPrincipalName(string userSID)
        {
            DirectoryEntry de = GetUser(userSID);
            if (de != null)
            {
                return de.Properties["userPrincipalName"][0].ToString();
            }

            return string.Empty;
        }

        private UserInfo GetUserInfoBySID(string userSID)
        {
            string userPrincipalName = GetUserPrincipalName(userSID);
            if (userPrincipalName != null && userPrincipalName != string.Empty)
            {
                UserController uc = new UserController();
                List<UserInfo> uiList = uc.SelectUsers();
                foreach (UserInfo ui in uiList)
                {
                    if (ui.UserName == userPrincipalName)
                        return ui;
                }
            }

            return null;

        }


        private DirectoryEntry GetUser(string userSID)
        {
            adSecurity ad = new adSecurity();
            return ad.GetUserBySID(userSID);
        }

        private DirectoryEntry GetUserByUPN(string upn)
        {
            adSecurity ad = new adSecurity();
            return ad.GetUserByUPN(upn);
        }

        private void ResetPhones(Guid userId)
        {

            RijndaelEnhanced re = new RijndaelEnhanced();
            AppConfig ac = new AppConfig();


            PhoneController pc = new PhoneController();
            List<PhoneInfo> piList = pc.SelectPhonesByUser(userId);
            foreach (PhoneInfo pi in piList)
            {
                if (pi.IpAddress != null)
                {
                 
                    try
                    {
                        PhoneCommand ph = new PhoneCommand(pi, PhoneCommand.CommandType.Reboot);
                        Thread thPhCmd = new Thread(new ThreadStart(ph.SendCommand));
                        thPhCmd.Start();
                        LogServerEvent(pi.PhoneId, userId, pi.IpAddress, pi.MacAddress, "Password Updated: Reboot command sent to phone.", "Information");
                    }
                    catch {}
                }

            }
        }

        #endregion

        #region Event Log

        private void LogEvent(string UserName, string userSid, string EventMessage, string EventType)
        {
            EventLog el = new EventLog();
            el.LogEvent(Guid.Empty, Guid.Empty, string.Empty, string.Empty, "Client - " + userSid, "Web Service", UserName + " - " + EventMessage, EventType);
        }

        private void LogServerEvent(Guid phoneId, Guid userId, string ipAddress, string macAddress, string EventMessage, string EventType)
        {
            EventLog el = new EventLog();
            el.LogEvent(phoneId, userId, macAddress, ipAddress, "Snomatastic Server", "Web Service", EventMessage, EventType);
        }

        #endregion



    }
}
